import dayjs from 'dayjs'
import holiday2015 from '../data/2015-holiday.json'
import holiday2016 from '../data/2016-holiday.json'
import holiday2017 from '../data/2017-holiday.json'
import holiday2018 from '../data/2018-holiday.json'
import holiday2019 from '../data/2019-holiday.json'
import holiday2020 from '../data/2020-holiday.json'
import holiday2021 from '../data/2021-holiday.json'
import holiday2022 from '../data/2022-holiday.json'
import holiday2023 from '../data/2023-holiday.json'
import holiday2024 from '../data/2024-holiday.json'
import holiday2025 from '../data/2025-holiday.json'

/**
 * 节假日工具函数
 */
class HolidayUtils {
  constructor() {
    this.holidayMap = new Map()
    this.yearDataMap = new Map()
    this.loadAllHolidayData()
  }

  /**
   * 加载所有年份的节假日数据到内存中，提高查询效率
   */
  loadAllHolidayData() {
    const holidayDataSources = [
      holiday2015,
      holiday2016,
      holiday2017,
      holiday2018,
      holiday2019,
      holiday2020,
      holiday2021,
      holiday2022,
      holiday2023,
      holiday2024,
      holiday2025,
      // 可以在这里添加更多年份的数据
    ]

    holidayDataSources.forEach((holidayData) => {
      if (holidayData && holidayData.days && holidayData.year) {
        // 存储年份数据的映射
        this.yearDataMap.set(holidayData.year, holidayData)

        // 存储具体日期的映射
        holidayData.days.forEach((holiday) => {
          this.holidayMap.set(holiday.date, {
            name: holiday.name,
            isOffDay: holiday.isOffDay,
            year: holidayData.year,
          })
        })
      }
    })
  }

  /**
   * 获取已加载的年份列表
   * @returns {Array<number>} 可用的年份列表
   */
  getAvailableYears() {
    return Array.from(this.yearDataMap.keys()).sort((a, b) => a - b)
  }

  /**
   * 检查指定年份的节假日数据是否已加载
   * @param {number} year - 年份
   * @returns {boolean} 是否已加载
   */
  isYearDataAvailable(year) {
    return this.yearDataMap.has(year)
  }

  /**
   * 获取指定年份的节假日数据统计
   * @param {number} year - 年份
   * @returns {Object} 年份统计信息
   */
  getYearStatistics(year = dayjs().year()) {
    if (!this.yearDataMap.has(year)) {
      return {
        year,
        available: false,
        totalDays: 0,
        holidayDays: 0,
        workingDays: 0,
      }
    }

    const yearData = this.yearDataMap.get(year)
    const holidayDays = yearData.days.filter((day) => day.isOffDay).length
    const workingDays = yearData.days.filter((day) => !day.isOffDay).length

    return {
      year,
      available: true,
      totalDays: yearData.days.length,
      holidayDays,
      workingDays,
      holidays: yearData.days.reduce((acc, day) => {
        const holidayName = day.name
        if (!acc[holidayName]) {
          acc[holidayName] = { holiday: 0, working: 0 }
        }
        if (day.isOffDay) {
          acc[holidayName].holiday++
        } else {
          acc[holidayName].working++
        }
        return acc
      }, {}),
    }
  }

  /**
   * 判断指定日期是否在节假日配置中
   * @param {string|Date|dayjs} date - 日期
   * @returns {Object|null} 节假日信息，如果不是节假日返回null
   */
  getHolidayInfo(date) {
    const dateString = dayjs(date).format('YYYY-MM-DD')
    return this.holidayMap.get(dateString) || null
  }

  /**
   * 判断是否是法定节假日（放假）
   * @param {string|Date|dayjs} date - 日期
   * @returns {boolean} true: 是节假日(放假), false: 不是节假日
   */
  isHoliday(date) {
    const holidayInfo = this.getHolidayInfo(date)
    return holidayInfo ? holidayInfo.isOffDay : false
  }

  /**
   * 判断是否是调休工作日（节假日期间需要上班的日期）
   * @param {string|Date|dayjs} date - 日期
   * @returns {boolean} true: 是调休工作日, false: 不是调休工作日
   */
  isWorkdayFromHoliday(date) {
    const holidayInfo = this.getHolidayInfo(date)
    return holidayInfo ? !holidayInfo.isOffDay : false
  }

  /**
   * 综合判断是否是工作日
   * 考虑周末、法定节假日、调休等因素
   * @param {string|Date|dayjs} date - 日期
   * @returns {boolean} true: 是工作日, false: 不是工作日
   */
  isWorkday(date) {
    const dayObj = dayjs(date)
    const dayOfWeek = dayObj.day() // 0=周日, 1=周一, ..., 6=周六

    // 先检查是否在节假日配置中
    const holidayInfo = this.getHolidayInfo(date)
    if (holidayInfo) {
      // 如果在节假日配置中，以配置为准
      // isOffDay: true -> 放假，返回false (不是工作日)
      // isOffDay: false -> 调休上班，返回true (是工作日)
      return !holidayInfo.isOffDay
    }

    // 如果不在节假日配置中，按常规逻辑判断
    // 周一到周五是工作日，周末不是工作日
    return dayOfWeek >= 1 && dayOfWeek <= 5
  }

  /**
   * 获取工作日所需的标准工时
   * @param {string|Date|dayjs} date - 日期
   * @returns {number} 标准工时（小时）
   */
  getRequiredHours(date) {
    return this.isWorkday(date) ? 8 : 0
  }

  /**
   * 获取日期的类型描述
   * @param {string|Date|dayjs} date - 日期
   * @returns {string} 日期类型描述
   */
  getDayTypeDescription(date) {
    const dayObj = dayjs(date)
    const dayOfWeek = dayObj.day()
    const holidayInfo = this.getHolidayInfo(date)

    if (holidayInfo) {
      if (holidayInfo.isOffDay) {
        return `${holidayInfo.name}（放假）`
      } else {
        return `${holidayInfo.name}（调休上班）`
      }
    }

    // 常规日期
    if (dayOfWeek === 0) return '周日'
    if (dayOfWeek === 6) return '周六'
    return '工作日'
  }

  /**
   * 获取指定年份的所有节假日
   * @param {number} year - 年份，默认为当前年份
   * @returns {Array} 节假日列表
   */
  getHolidaysByYear(year = dayjs().year()) {
    const holidays = []
    this.holidayMap.forEach((info, date) => {
      if (date.startsWith(year.toString())) {
        holidays.push({
          date,
          ...info,
        })
      }
    })
    return holidays.sort((a, b) => a.date.localeCompare(b.date))
  }

  /**
   * 获取指定月份的节假日
   * @param {number} year - 年份，默认为当前年份
   * @param {number} month - 月份 (1-12)
   * @returns {Array} 节假日列表
   */
  getHolidaysByMonth(year = dayjs().year(), month) {
    const monthStr = String(month).padStart(2, '0')
    const prefix = `${year}-${monthStr}`

    const holidays = []
    this.holidayMap.forEach((info, date) => {
      if (date.startsWith(prefix)) {
        holidays.push({
          date,
          ...info,
        })
      }
    })
    return holidays.sort((a, b) => a.date.localeCompare(b.date))
  }
}

// 创建单例实例
const holidayUtils = new HolidayUtils()

export default holidayUtils

// 导出常用方法的简化调用
export const isHoliday = (date) => holidayUtils.isHoliday(date)
export const isWorkday = (date) => holidayUtils.isWorkday(date)
export const getRequiredHours = (date) => holidayUtils.getRequiredHours(date)
export const getDayTypeDescription = (date) =>
  holidayUtils.getDayTypeDescription(date)
export const getHolidayInfo = (date) => holidayUtils.getHolidayInfo(date)

// 多年份数据相关方法
export const getAvailableYears = () => holidayUtils.getAvailableYears()
export const isYearDataAvailable = (year) =>
  holidayUtils.isYearDataAvailable(year)
export const getYearStatistics = (year) => holidayUtils.getYearStatistics(year)
export const getHolidaysByYear = (year) => holidayUtils.getHolidaysByYear(year)
export const getHolidaysByMonth = (year, month) =>
  holidayUtils.getHolidaysByMonth(year, month)
